package club.xyes.zkh.ecommerce.web.api.controller;

import club.xyes.zkh.ecommerce.commons.context.ApplicationConstants;
import club.xyes.zkh.ecommerce.commons.dto.AccessLogExportData;
import club.xyes.zkh.ecommerce.commons.dto.MinimalUserInfo;
import club.xyes.zkh.ecommerce.commons.entity.Shop;
import club.xyes.zkh.ecommerce.commons.entity.User;
import club.xyes.zkh.ecommerce.commons.entity.UserAccessShopLog;
import club.xyes.zkh.ecommerce.commons.properties.WebsiteConfigurationProperties;
import club.xyes.zkh.ecommerce.commons.util.EntityImagePathUtils;
import club.xyes.zkh.ecommerce.commons.util.ExcelUtils;
import club.xyes.zkh.ecommerce.commons.vo.GeneralResult;
import club.xyes.zkh.ecommerce.service.UserAccessShopLogService;
import club.xyes.zkh.ecommerce.service.UserService;
import club.xyes.zkh.ecommerce.web.controller.BaseController;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Create by 郭文梁 2019/4/18 0018 14:10
 * UserAccessShopLogController
 * 用户商铺访问记录相关数据访问控制器
 *
 * @author 郭文梁
 * @data 2019/4/18 0018
 */
@RestController
@RequestMapping("/api/user-access-shop-log")
public class UserAccessShopLogController extends BaseController<UserAccessShopLog> {
    private static final List<String> EXCEL_HEADERS = Arrays.asList(
            "商铺名", "用户名", "用户电话", "总消费金额", "总消费次数", "最后一次消费时间");
    private static final int DEFAULT_PAGE = 1;
    private static final int DEFAULT_ROWS = 10;
    private final UserAccessShopLogService service;
    private final UserService userService;
    private final WebsiteConfigurationProperties websiteConfigurationProperties;

    @Autowired
    public UserAccessShopLogController(UserAccessShopLogService service,
                                       UserService userService,
                                       WebsiteConfigurationProperties websiteConfigurationProperties) {
        super(service);
        this.service = service;
        this.userService = userService;
        this.websiteConfigurationProperties = websiteConfigurationProperties;
    }

    /**
     * 获取当前用户的访问记录
     *
     * @param page 页码
     * @param rows 每页大小
     * @return GCR
     */
    @ApiOperation("获取当前用户的访问记录")
    @GetMapping("/mine")
    public GeneralResult<PageInfo<UserAccessShopLog>> mine(Integer page,
                                                           Integer rows) {
        page = page == null ? DEFAULT_PAGE : page;
        rows = rows == null ? DEFAULT_ROWS : rows;
        @NotNull MinimalUserInfo userInfo = getRequiredUserInfo();
        User user = userService.getRequired(userInfo.getUserId());
        PageInfo<UserAccessShopLog> logPageInfo = service.findByUser(user, page, rows);
        List<UserAccessShopLog> logList = logPageInfo.getList().stream().peek(log -> {
            Shop shop = log.getShop();
            Shop res = EntityImagePathUtils.prettyLogoPath(shop,
                    websiteConfigurationProperties.getStaticServerPrefix(),
                    websiteConfigurationProperties.getShopLogoPath());
            log.setShop(res);
        }).collect(Collectors.toList());
        logPageInfo.setList(logList);
        return GeneralResult.ok(logPageInfo);
    }

    /**
     * 通过商铺ID查询访问记录
     *
     * @param shopId   商铺ID
     * @param page     页码
     * @param rows     每页大小
     * @param username 用户名搜索条件
     * @return GR
     */
    @ApiOperation("通过商铺ID查询访问记录")
    @GetMapping("/shop/{shopId}")
    public GeneralResult<?> findByShop(@PathVariable("shopId") Integer shopId,
                                       @RequestParam("order") String order,
                                       @RequestParam("type") String type,
                                       String username,
                                       Integer page, Integer rows) {
        if (
                !(ApplicationConstants.Database.ORDER_DESC.equals(order)
                        || ApplicationConstants.Database.ORDER_ASC.equals(order))
        ) {
            return GeneralResult.badRequest("Unknown order type:" + order);
        }
        page = page == null ? DEFAULT_PAGE : page;
        rows = rows == null ? DEFAULT_ROWS : rows;
        username = username == null ? "" : username;
        PageInfo<UserAccessShopLog> logs;
        switch (type) {
            case "time":
            case "amount":
            case "frequency":
            case "level":
                logs = service.findByShopIdAndOrder(shopId, username, type, order, page, rows);
                break;
            default:
                return GeneralResult.badRequest("Unknown type:" + type);
        }

        String serverPrefix = websiteConfigurationProperties.getStaticServerPrefix();
        String shopLogoPath = websiteConfigurationProperties.getShopLogoPath();
        logs.setList(logs.getList().stream()
                .peek(log -> EntityImagePathUtils.prettyLogoPath(log.getShop(), serverPrefix, shopLogoPath))
                .collect(Collectors.toList()));
        return GeneralResult.ok(logs);
    }

    /**
     * 通过用户名搜索在店铺消费的用户
     *
     * @param shopId   商铺ID
     * @param username 用户名
     * @return GR
     */
    @GetMapping("/shop/{shopId}/search")
    @ApiOperation("根据用户名搜索在商铺消费过的用户")
    public GeneralResult<?> searchByUsername(@PathVariable("shopId") Integer shopId,
                                             @RequestParam("username") String username) {
        List<UserAccessShopLog> logs = service.findLikeUsername(shopId, username);
        return GeneralResult.ok(logs);
    }

    /**
     * 转换为Excel二进制
     *
     * @return rb
     * @throws IOException IO异常
     */
    @GetMapping("/shop/export")
    @ApiOperation("导出当前商铺的用户访问记录")
    public ResponseEntity<byte[]> exportExcel() throws IOException {
        List<AccessLogExportData> logs = service.findExportDataByShopId(getRequiredShopInfo().getShopId());
        List<List<String>> cols = ExcelUtils.toColsData(logs);
        byte[] body = ExcelUtils.toExcel(EXCEL_HEADERS, cols);
        return ResponseEntity
                .status(HttpStatus.OK)
                .header("Content-Disposition", "attachment; filename=accessLog.xls")
                .header("Content-Type", "application/vnd.ms-excel")
                .body(body);
    }

    /**
     * 导出指定商铺的用户访问记录
     *
     * @param shopId 商铺ID
     * @return RE
     */
    @GetMapping("/shop/{shopId}/export")
    @ApiOperation("导出指定商铺的用户访问记录")
    public ResponseEntity<byte[]> exportExcel(@PathVariable("shopId") Integer shopId) throws IOException {
        List<AccessLogExportData> logs = service.findExportDataByShopId(shopId);
        List<List<String>> cols = ExcelUtils.toColsData(logs);
        byte[] body = ExcelUtils.toExcel(EXCEL_HEADERS, cols);
        return ResponseEntity
                .status(HttpStatus.OK)
                .header("Content-Disposition", "attachment; filename=accessLog.xls")
                .header("Content-Type", "application/vnd.ms-excel")
                .body(body);
    }
}
